package com.taxx.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.taxx.dto.LoginRequest;
import com.taxx.dto.LoginResponse;
import com.taxx.entity.SysUser;
import com.taxx.entity.SysUserRole;
import com.taxx.mapper.SysUserMapper;
import com.taxx.mapper.SysUserRoleMapper;
import com.taxx.service.SysUserService;
import com.taxx.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
import com.taxx.entity.SysRole;

/**
 * 系统用户服务实现类
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
    
    @Autowired
    private SysUserMapper userMapper;
    
    @Autowired
    private SysUserRoleMapper userRoleMapper;
    
    @Autowired
    private JwtUtil jwtUtil;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Autowired
    private HttpServletRequest request;
    
    @Override
    public LoginResponse login(LoginRequest request) {
        // 查询用户
        SysUser user = userMapper.findByUsername(request.getUsername());
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 检查用户状态
        if (user.getStatus() != 1) {
            throw new RuntimeException("用户已被禁用");
        }
        
        // 验证密码
        if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
            throw new RuntimeException("密码错误");
        }
        
        // 获取用户角色
        List<String> roleCodes = userRoleMapper.selectRoleCodesByUserId(user.getId());
        
        // 生成JWT令牌
        String accessToken = jwtUtil.generateToken(user.getUsername(), user.getId());
        
        // 更新最后登录信息
        updateLastLoginInfo(user);
        
        // 构建响应
        LoginResponse response = new LoginResponse();
        response.setAccessToken(accessToken);
        response.setExpiresIn(86400L); // 24小时
        
        LoginResponse.UserInfo userInfo = new LoginResponse.UserInfo();
        userInfo.setId(user.getId());
        userInfo.setUsername(user.getUsername());
        userInfo.setRealName(user.getRealName());
        userInfo.setEmail(user.getEmail());
        userInfo.setPhone(user.getPhone());
        userInfo.setAvatar(user.getAvatar());
        userInfo.setStatus(user.getStatus());
        userInfo.setRoles(roleCodes);
        
        response.setUserInfo(userInfo);
        
        return response;
    }
    
    @Override
    public void logout(String token) {
        // 这里可以实现令牌黑名单等逻辑
        // 暂时简单处理
    }
    
    @Override
    public String refreshToken(String token) {
        if (jwtUtil.isTokenExpired(token)) {
            throw new RuntimeException("令牌已过期");
        }
        return jwtUtil.refreshToken(token);
    }
    
    @Override
    public SysUser getUserInfo(Long userId) {
        return userMapper.selectById(userId);
    }
    
    @Override
    public List<SysUser> getUserList() {
        List<SysUser> users = list();
        
        // 为每个用户加载角色信息
        for (SysUser user : users) {
            List<SysRole> roles = getUserRoles(user.getId());
            user.setRoles(roles);
        }
        
        return users;
    }
    
    @Override
    @Transactional
    public boolean createUser(SysUser user, List<Long> roleIds) {
        // 检查用户名是否已存在
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("username", user.getUsername());
        if (userMapper.selectCount(wrapper) > 0) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 加密密码
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        user.setStatus(1);
        
        // 保存用户
        boolean success = save(user);
        if (success && roleIds != null && !roleIds.isEmpty()) {
            // 保存用户角色关联
            for (Long roleId : roleIds) {
                SysUserRole userRole = new SysUserRole();
                userRole.setUserId(user.getId());
                userRole.setRoleId(roleId);
                userRoleMapper.insert(userRole);
            }
        }
        
        return success;
    }
    
    @Override
    @Transactional
    public boolean updateUser(SysUser user, List<Long> roleIds) {
        // 检查用户名是否已被其他用户使用
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("username", user.getUsername())
                .ne("id", user.getId());
        if (userMapper.selectCount(wrapper) > 0) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 如果密码不为空，则加密密码
        if (StringUtils.hasText(user.getPassword())) {
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        } else {
            user.setPassword(null); // 不更新密码
        }
        
        // 更新用户
        boolean success = updateById(user);
        if (success && roleIds != null) {
            // 删除原有角色关联
            QueryWrapper<SysUserRole> roleWrapper = new QueryWrapper<>();
            roleWrapper.eq("user_id", user.getId());
            userRoleMapper.delete(roleWrapper);
            
            // 保存新的角色关联
            for (Long roleId : roleIds) {
                SysUserRole userRole = new SysUserRole();
                userRole.setUserId(user.getId());
                userRole.setRoleId(roleId);
                userRoleMapper.insert(userRole);
            }
        }
        
        return success;
    }
    
    @Override
    @Transactional
    public boolean deleteUser(Long userId) {
        // 删除用户角色关联
        QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        userRoleMapper.delete(wrapper);
        
        // 删除用户（逻辑删除）
        return removeById(userId);
    }
    
    @Override
    public boolean changePassword(Long userId, String oldPassword, String newPassword) {
        SysUser user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 验证旧密码
        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            throw new RuntimeException("原密码错误");
        }
        
        // 更新密码
        user.setPassword(passwordEncoder.encode(newPassword));
        return updateById(user);
    }
    
    @Override
    public boolean resetPassword(Long userId, String newPassword) {
        SysUser user = new SysUser();
        user.setId(userId);
        user.setPassword(passwordEncoder.encode(newPassword));
        return updateById(user);
    }
    
    @Override
    public boolean updateUserStatus(Long userId, Integer status) {
        SysUser user = new SysUser();
        user.setId(userId);
        user.setStatus(status);
        user.setUpdateTime(LocalDateTime.now());
        return updateById(user);
    }

    @Override
    @Transactional
    public boolean assignRoles(Long userId, List<Long> roleIds) {
        try {
            // 先删除用户的所有角色
            userRoleMapper.deleteByUserId(userId);
            
            // 如果角色ID列表不为空，则添加新角色
            if (roleIds != null && !roleIds.isEmpty()) {
                List<SysUserRole> userRoles = roleIds.stream()
                    .map(roleId -> {
                        SysUserRole userRole = new SysUserRole();
                        userRole.setUserId(userId);
                        userRole.setRoleId(roleId);
                        userRole.setCreateTime(LocalDateTime.now());
                        return userRole;
                    })
                    .collect(Collectors.toList());
                
                userRoleMapper.insertBatch(userRoles);
            }
            
            return true;
        } catch (Exception e) {
            throw new RuntimeException("角色分配失败: " + e.getMessage());
        }
    }

    @Override
    public List<SysRole> getUserRoles(Long userId) {
        return userRoleMapper.selectRolesByUserId(userId);
    }

    @Override
    @Transactional
    public boolean removeUserRole(Long userId, Long roleId) {
        try {
            return userRoleMapper.deleteByUserIdAndRoleId(userId, roleId) > 0;
        } catch (Exception e) {
            throw new RuntimeException("角色移除失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public boolean batchAssignRoles(List<Long> userIds, List<Long> roleIds) {
        try {
            for (Long userId : userIds) {
                assignRoles(userId, roleIds);
            }
            return true;
        } catch (Exception e) {
            throw new RuntimeException("批量角色分配失败: " + e.getMessage());
        }
    }
    
    /**
     * 更新最后登录信息
     */
    private void updateLastLoginInfo(SysUser user) {
        user.setLastLoginTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        user.setLastLoginIp(getClientIp());
        updateById(user);
    }
    
    /**
     * 获取客户端IP地址
     */
    private String getClientIp() {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}

